package com.midian.service.activity.impl;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.deser.ValueInstantiators.Base;
import org.springframework.stereotype.Service;

import com.midian.common.dao.BaseDaoBySql;
import com.midian.common.dao.BaseDaoTemplet;
import com.midian.common.dao.OrderHelper;
import com.midian.common.dao.SearchHelper;
import com.midian.common.dao.SearchHelper.Type;
import com.midian.common.exception.BizException;
import com.midian.common.pager.Pager;
import com.midian.common.pay.common.util.PayUtils;
import com.midian.common.pay.common.util.iorder.OpOrder;
import com.midian.common.system.SysStatic;
import com.midian.controller.activity.ActivityController;
import com.midian.model.activity.Activity;
import com.midian.model.activity.ActivityUser;
import com.midian.service.activity.IActivityService;
import com.midian.service.activity.IActivityUserService;
import com.midian.service.common.BaseService;
import com.sun.xml.internal.bind.v2.model.core.ID;

/**
 * 活动用户（报名）业务实现类
 * @author Mengfh
 *
 */
@Service("activityUserService")
public class ActivityUserServiceImpl extends BaseService implements IActivityUserService {
	/** 日志 */
	private static Logger LOG = Logger.getLogger(ActivityUserServiceImpl.class);
	/**活动用户（报名）DAO*/
	private BaseDaoBySql<ActivityUser> activityUserDAO;
	
	private BaseDaoBySql<Activity> activityDao;
	
	@Resource(name = "activityDAO")
	public void setActivityDao(BaseDaoBySql<Activity> activityDao) {
		this.activityDao = activityDao;
	}
	
	

	@Resource(name = "activityUserDAO")
	public void setActivityUserDAO(BaseDaoBySql<ActivityUser> activityUserDAO) {
		this.activityUserDAO = activityUserDAO;
	}

	@Override
	public ActivityUser add(ActivityUser target) throws BizException {
		this.activityUserDAO.add(target);
		return target;
	}

	@Override
	public void update(ActivityUser target) throws BizException {
		this.activityUserDAO.updateByConvertHql(target);
	}

	@Override
	public void delete(Serializable id) throws BizException {
		this.activityUserDAO.delete(id);
	}

	@Override
	public void delete(Serializable[] ids) throws BizException {
		this.activityUserDAO.delete(ids);
	}

	@Override
	public ActivityUser get(Serializable id) throws BizException {
		return this.activityUserDAO.get(id);
	}

	@Override
	public List<ActivityUser> showList(ActivityUser target, Pager pager, List<OrderHelper> helper) throws BizException {
		return this.activityUserDAO.find(target, getSearchHelper(), helper, pager);
	}

	@Override
	public void opDelFlag(Serializable[] ids, Integer status) throws BizException {
		this.activityUserDAO.opDelFlag(ids, status);
	}

	@Override
	protected List<SearchHelper> getSearchHelper() {
		String[] attrs = {};
		Type[] types = {};
		return SearchHelper.getSearchList(attrs, types);
	}

	@Override
	public ActivityUser getActivityUser(String activityId, String userId,Integer joinState) {
		String hql = "from ActivityUser where activityId = ? and joinUserId = ? and joinState = ?";
		return (ActivityUser) this.activityUserDAO.findObject(hql, new Object[]{activityId, userId,joinState});
	}
	
	@Override
	public List<Activity> getMyActivities(String user_id, String activity_filter, Pager pager) {
		List<Activity> activities = null;
		StringBuilder sql = new StringBuilder();
		sql.append("select au.activityId as 'id',au.coverPicId,au.title,au.beginTime,aType.typeName,o.name as 'organizationName',");
		sql.append("au.adultPrice,au.childPrice,a.ages,a.activityAddress,a.activityAddressLon,");
		sql.append("a.activityAddressLat ");

		sql.append(" from activity_user au ");
		sql.append("left join activity a on a.id = au.activityId ");
		sql.append("left join activity_type aType on aType.id = a.typeId ");
		sql.append("left join organization o on o.id = a.organizationId ");
		sql.append("where au.joinUserId = ? and au.deleteFlag = ? and a.deleteFlag = ? and au.joinState = ? ");

		// 活动过滤
		if (StringUtils.isNotBlank(activity_filter)) {
			if("1".equals(activity_filter)){//活动未开始
				sql.append("and au.beginTime > now() ");
			}else if("2".equals(activity_filter)){//活动已经开始
				sql.append("and au.beginTime < now() ");
			}
		}
		
		List<Object> values = new ArrayList<Object>();
		values.add(user_id);
		values.add(SysStatic.NORMALDELFLAG);
		values.add(SysStatic.NORMALDELFLAG);
		values.add("1");
		return activityUserDAO.pageFindBySqlWithFieldNames(sql.toString(), values.toArray(), pager, Activity.class);

	}
	
	/**
	 * 根据订单号查询相应实体
	 * @param orderNo
	 * @return
	 */
	@SuppressWarnings("unused")
	private ActivityUser getActivityUserByOrderNo(String orderNo){
		String hql = "from ActivityUser where orderSn = ?";
		return (ActivityUser) activityUserDAO.findObject(hql, new Object[]{orderNo});
	}
	
	
	/**
	 * 购买广告位支付宝回调
	 * @param request
	 * @param response
	 * @param payType 支付类型
	 */
	@Override
	public void payCallback(HttpServletRequest request, HttpServletResponse response,Integer payType) throws BizException {
		// 支付宝回调方法
		if(PayUtils.PAY_TYPE_ALI.equals(payType)){	
			LOG.debug("============【ActivityUserService】开始执行支付宝回调方法==============");
			PayUtils.aliCallback(request, response, new OpOrder() {
				
				@Override
				public void postOrdered(Double payedMoney, Integer payStatus, String callback, String orderNo,
						String tradeNo) {
					LOG.debug("============【ActivityUserService】开始执行支付宝回调后更新一系列数据================");
					updateOrderInfo(payedMoney,  payStatus, callback, orderNo,tradeNo,PayUtils.PAY_TYPE_ALI);
				}
			});
		}
		// 微信回调
		else if(PayUtils.PAY_TYPE_WX.equals(payType)){
			LOG.debug("============【ActivityUserService】开始执行微信回调方法==============");
			try {
				PayUtils.wxCallback(request, response, new OpOrder() {
					@Override
					public void postOrdered(Double payedMoney, Integer payStatus, String callback, String orderNo,
							String tradeNo) {
						LOG.debug("============【ActivityUserService】开始执行微信回调后更新一系列数据================");
						updateOrderInfo(payedMoney,  payStatus, callback, orderNo,tradeNo,PayUtils.PAY_TYPE_WX);
					}
				});
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * 回调后需要更新的一系列数据
	 * @param payedMoney 应付金额
	 * @param payStatus 支付状态
	 * @param callback 回调信息
	 * @param orderNo 订单信息
	 * @throws BizException 
	 */
	private void updateOrderInfo(Double payedMoney,  Integer payStatus, String callback, String orderNo,String tradeNo,Integer payType){
		LOG.info("支付回调信息"+callback);
		LOG.debug("===============【ActivityUserService】进入回调成功后更新数据的方法=================");
		
		try {
			if(!"".equals(orderNo)){
				//查询activity_user by orderno
				ActivityUser activityUser =  this.getActivityUserByOrderNo(orderNo);
				if(activityUser != null){
					if("".equals(activityUser.getIsPayCallback()) || activityUser.getIsPayCallback() ==null){
						String hqlUpdate = "update ActivityUser o set o.isPayCallback = ? where orderSn = ?";
						Object[] values = { Integer.valueOf(1), orderNo };
						LOG.debug("============【ActivityUserService】如果此订单号取到的activityUser不为空，设置isPayCallback回调值为1=============orderNo="+orderNo);
						if (payStatus == PayUtils.PAY_STATUS_PAYED)
						{
							LOG.debug("===========【ActivityUserService】如果支付状态PAY_STATUS_PAYED为2（已支付）============");
							hqlUpdate = "update ActivityUser o set o.isPayCallback = ?,joinState = ?,payedMoney = ? where orderSn = ?";
							values = new Object[] { Integer.valueOf(1), Integer.valueOf(1), payedMoney, orderNo };
							LOG.debug("===========【ActivityUserService】更新此订单的回调值为1，相应的付款金额，订单号============orderNo="+orderNo);
							
							
							String hql = "from Activity  a where a.id = ?";
							/**付款成功后活动人数累加*/
							Activity activity = (Activity) this.activityDao.findObject(hql, new Object[]{activityUser.getActivityId()});
							
							LOG.debug("===================【ActivityUserService】开始累加活动人数=========================活动标题="+activity.getTitle());
							if (activity!=null) {
								activity.setJoinCount(activity.getJoinCount()+activityUser.getAdultCount()+activityUser.getChildCount());
								LOG.debug("===================【ActivityUserService】累加完成之后活动人数========================="+activity.getJoinCount());
								this.activityDao.update(activity);
								LOG.debug("===================【ActivityUserService】活动信息写入数据库完成,活动标题========================="+activity.getTitle()+"====已报名人数===="+activity.getJoinCount());
								
							}
							
							
						}
						this.activityUserDAO.update(hqlUpdate, values);
						LOG.debug("===================【ActivityUserService】用户ispaycallback,joinstate,paymoney信息写入数据库,订单号=========================orderNo="+activityUser.getOrderSn());
					}
				}
			}
			
			
			
		} catch (Exception e) {
			LOG.error(e.getMessage());
		}
	}


	//根据已经报名的用户id和对应的活动id查出对应的成功报名的activityUser
	@Override
	public ActivityUser getByUserIdAndActivity(String userId, String activityId) throws BizException {
		String hql = "from ActivityUser  a where a.joinUserId = ? and activityId = ? and joinState=1";
		return (ActivityUser) this.activityUserDAO.findObject(hql,  new Object[]{userId,activityId});
	}
	
}
